package com.tbit.uqbike.webmanager.util.aliyun;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.OssConfig;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.UUID;


/**
 * @Author: chen
 * @Description:
 * @Date: 创建于 10:50 2020/8/3
 */
public class OssFileUtils {

    private final static Logger log = Logger.getLogger(OssFileUtils.class);
    public static Integer IMAGE = 2;
    public static Integer MP3 = 1;

    /**
     * @Description:
     * @Param: [inputStream, oosConfig, fileName, contentType, isMuisc(1代表map文件，2代表image)]
     * @return: java.lang.String
     * @Author: Jing
     * @Date: 2021/5/24
     */
    public static String uploadByAliYun(InputStream inputStream, OssConfig oosConfig, String fileName, String contentType, int isMuisc) throws Exception {
        /**判断文件大小*/
        //开始压缩图片
        if (isMuisc == 2 && (!"image/gif".equals(contentType) && !"application/pdf".equals(contentType))) {
            inputStream = compress(inputStream);
        }
        //上传到阿里云
        OSSClient ossClient = new OSSClient(oosConfig.getEndpoint(), oosConfig.getAccessKeyId(), oosConfig.getAccessKeySecret());
        /*ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(instream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        objectMetadata.setContentType(getcontentType(contentType));
        objectMetadata.setContentDisposition("inline;filename=" + fileName);

        // 指定上传文件操作时是否覆盖同名Object。
        // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
        // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
        // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
        objectMetadata.setHeader("x-oss-forbid-overwrite", "false");*/
        PutObjectRequest putObjectRequest = new PutObjectRequest(oosConfig.getBucketName(), fileName, inputStream);
        putObjectRequest.setMetadata(init(inputStream, fileName, contentType));
        // 上传文件。
        ossClient.putObject(putObjectRequest);
        //ossClient.putObject(oosConfig.getBucketName(), fileName, instream,objectMetadata);
        ossClient.shutdown();
        return "https://" + oosConfig.getBucketName() + "." + oosConfig.getEndpoint() + "/" + fileName;
    }

    public static ObjectMetadata init(InputStream inputStream, String fileName, String contentType) throws IOException {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(inputStream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        objectMetadata.setContentType(contentType);
        objectMetadata.setContentDisposition("inline;filename=" + fileName);

        // 指定上传文件操作时是否覆盖同名Object。
        // 不指定x-oss-forbid-overwrite时，默认覆盖同名Object。
        // 指定x-oss-forbid-overwrite为false时，表示允许覆盖同名Object。
        // 指定x-oss-forbid-overwrite为true时，表示禁止覆盖同名Object，如果同名Object已存在，程序将报错。
        objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
        return objectMetadata;
    }


    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     *
     * @param FilenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if ("bmp".equalsIgnoreCase(FilenameExtension)) {
            return "image/bmp";
        }
        if ("gif".equalsIgnoreCase(FilenameExtension)) {
            return "image/gif";
        }
        if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
                "jpg".equalsIgnoreCase(FilenameExtension)
        ) {
            return "image/jpeg";
        }
        if ("png".equalsIgnoreCase(FilenameExtension)) {
            return "image/png";
        }
        if ("html".equalsIgnoreCase(FilenameExtension)) {
            return "text/html";
        }
        if ("txt".equalsIgnoreCase(FilenameExtension)) {
            return "text/plain";
        }
        if ("vsd".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.visio";
        }
        if ("pptx".equalsIgnoreCase(FilenameExtension) ||
                "ppt".equalsIgnoreCase(FilenameExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if ("docx".equalsIgnoreCase(FilenameExtension) ||
                "doc".equalsIgnoreCase(FilenameExtension)) {
            return "application/msword";
        }
        if ("xml".equalsIgnoreCase(FilenameExtension)) {
            return "text/xml";
        }
        if ("mp3".equalsIgnoreCase(FilenameExtension)) {
            return "audio/mp3";
        }
        if ("mp4".equalsIgnoreCase(FilenameExtension)) {
            return "video/mpeg4";
        }
        if ("wav".equalsIgnoreCase(FilenameExtension)) {
            return "audio/wav";
        }
        if ("zip".equalsIgnoreCase(FilenameExtension)) {
            return "aplication/zip";
        }
        return "image/jpeg";
    }


    /**
     * 压缩图片(没有原图)
     * 默认输出25%质量图片
     *
     * @param
     * @return
     * @throws IOException
     */
    public static InputStream compress(InputStream in) throws Exception {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        Thumbnails.of(in).scale(1f).outputQuality(0.25f).toOutputStream(os);
        InputStream is = new ByteArrayInputStream(os.toByteArray());
        in.close();
        os.close();
        return is;
    }


    /**
     * 上传压缩文件
     *
     * @param oosConfig
     * @param fileName
     * @param file
     * @return
     * @throws Exception
     */
    public static String uploadZip(OssConfig oosConfig, String fileName, File file) {
        try {
            InputStream inputStream = new FileInputStream(file);
            String url = OssFileUtils.uploadByAliYun(inputStream, oosConfig, fileName, "zip", 1);
            return url;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static String upload(MultipartFile file, OssConfig ossConfig) {
        String imageId = UUID.randomUUID() + file.getContentType();
        String fileUrl;
        try {
            InputStream inputStream = file.getInputStream();
            fileUrl = OssFileUtils.uploadByAliYun(inputStream, ossConfig, imageId, file.getContentType(), OssFileUtils.IMAGE);
        } catch (Exception e) {
            log.error("图片上传失败", e);
            throw new BaseException("图片上传失败");
        }
        if (StringUtils.isBlank(fileUrl)) {
            throw new BaseException("图片上传失败");
        }
        return fileUrl;
    }


    /**
     * 读取指定文件内容
     * @param bucketName    oss桶名
     * @param fileName      文件名称
     * @param ossConfig     oss配置
     * @return              文件内容字符串
     */
    public static String readFile(String bucketName, String fileName, OssConfig ossConfig, String objectPath) {
        OSSClient ossClient = new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());

        if (!ossClient.doesObjectExist(bucketName, objectPath + "/" + fileName)){
            throw new BaseException("文件不存在");
        }

        OSSObject ossObject = ossClient.getObject(bucketName, objectPath + "/" + fileName);
        InputStream inputStream = ossObject.getObjectContent();

        /*读取文件内容*/
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            StringBuilder fileContent = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                fileContent.append(line);
            }
            return fileContent.toString();
        }catch (Exception e) {
            log.error("读取文件失败", e);
            return null;
        } finally {
            ossClient.shutdown();
        }
    }


    /**
     * 创建文件并上传到oss
     * @param oosConfig     oss配置
     * @param bucketName    oss桶名
     * @param fileName      文件名称
     * @param content       文件内容
     */
    public static void createFileUpload(OssConfig oosConfig, String bucketName, String fileName, String objectPath, String content) {
        OSSClient ossClient = new OSSClient(oosConfig.getEndpoint(), oosConfig.getAccessKeyId(), oosConfig.getAccessKeySecret());
        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
            /*上传到oss*/
            ossClient.putObject(bucketName, objectPath + "/" + fileName, inputStream);
        } catch (Exception e) {
            log.error("创建文件上传oss异常:", e);
        } finally {
            ossClient.shutdown();
        }
    }


}
